package dao

import (
	"time"
	"sort"
	"strings"
	"strconv"
)

const (
	TopicTypeBanner = 1 //轮播图
	TopicTypeHot    = 3 //热门小说

	ChannelTypeMan   = 1 //男生
	ChannelTypeWoman = 2 //女生
)

var (
	appHash     = map[int]*SysApp{}
	catHash     = map[int]*SysCat{}
	tagHash     = map[int]*SysTag{}
	bookHash    = map[int]*Book{}
	hotHash     = map[int][]int{}
	bannerHash  = map[int][]int{}
	tagBookHash = map[int][]int{}
)

func LoadTable() error {
	db := GetSession()
	defer db.Close()

	// 应用表
	if err := db.
		Where("plat_short=?", "wxmp").
		And("is_linkage=?", 1).
		And("is_delete=?", 0).
		Find(&appHash); err != nil {
		return err
	}

	// 分类
	if err := db.
		Cols("id", "category_fullname", "category_shortname").
		Find(&catHash); err != nil {
		return err
	}

	// 标签
	if err := db.Find(&tagHash); err != nil {
		return err
	}

	// 书
	if err := db.
		Cols("id", "name", "desc", "category", "tags", "serial_id", "oss_url").
		Where("release_time <= ?", time.Now().Format("2006-01-02 15:04:05")).
		And("publish_status = ?", 1).
		Find(&bookHash); err != nil {
		return err
	}

	// 栏目配置
	topic := make([]*ConfigTopic, 0)
	if err := db.
		In("topic_type", TopicTypeBanner, TopicTypeHot).
		In("channel_type", ChannelTypeMan, ChannelTypeWoman).
		Asc("channel_type", "topic_type", "sort_id").
		Find(&topic); err != nil {
		return err
	}
	channelType := topic[0].ChannelType
	bannerList := make([]int, 0)
	hotList := make([]int, 0)
	for _, t := range topic {
		if t.ChannelType != channelType {
			bannerHash[channelType] = bannerList
			hotHash[channelType] = hotList

			channelType = t.ChannelType
			bannerList = make([]int, 0)
			hotList = make([]int, 0)
		}
		if t.TopicType == TopicTypeBanner {
			bannerList = append(bannerList, t.BookId)
		} else if t.TopicType == TopicTypeHot {
			hotList = append(hotList, t.BookId)
		}
	}
	bannerHash[channelType] = bannerList
	hotHash[channelType] = hotList

	// 标签对应的书本
	for _, tag := range tagHash {
		tagIdStr := strconv.Itoa(tag.Id)
		bookList := make(sort.IntSlice, 0)
		for _, book := range bookHash {
			if strings.Contains(","+book.Tags+",", ","+tagIdStr+",") {
				bookList = append(bookList, book.Id)
			}
		}
		sort.Stable(bookList)
		tagBookHash[tag.Id] = bookList
	}

	return nil
}

func GetAppList() []*SysApp {
	list := make([]*SysApp, 0)
	for _, app := range appHash {
		list = append(list, app)
	}
	return list
}

func GetAppById(id int) *SysApp {
	if app, find := appHash[id]; find {
		return app
	}
	return nil
}

func GetAppByName(name string) *SysApp {
	for _, app := range appHash {
		if app.AppShort == name {
			return app
		}
	}
	return nil
}

func GetBookById(id int) *Book {
	if book, find := bookHash[id]; find {
		return book
	}
	return nil
}

func GetBannerBookByUserSex(sex int) []*Book {
	list := make([]*Book, 0)
	switch {
	case sex == 1 || sex == 2:
		if banner, find := bannerHash[sex]; find {
			for _, id := range banner {
				list = append(list, bookHash[id])
			}
		}
	default:
		for _, banner := range bannerHash {
			for _, id := range banner {
				list = append(list, bookHash[id])
				if len(list) > 0 && len(list)%3 == 0 {
					break
				}
			}
		}
	}
	return list
}

func BookQueryLike(str string) []*Book {
	bookList := make([]*Book, 0)
	//①书名②标签③简介④分类
	bookIdHash := map[int]bool{}

	// 按书名查找
	for _, book := range bookHash {
		if strings.Contains(book.Name, str) {
			bookList = append(bookList, book)
			bookIdHash[book.Id] = true
		}
		if len(bookList) == 9 {
			return bookList
		}
	}

	// 按标签查找
	for tagId, tag := range tagHash {
		if strings.Contains(tag.TagName, str) {
			books := tagBookHash[tagId]
			for _, id := range books {
				if bookIdHash[id] {
					continue
				}
				bookList = append(bookList, bookHash[id])
				if len(bookList) == 9 {
					return bookList
				}
			}
		}
	}

	// 按简介查找
	for _, book := range bookHash {
		if bookIdHash[book.Id] {
			continue
		}
		if strings.Contains(book.Desc, str) {
			bookList = append(bookList, book)
		}
		if len(bookList) == 9 {
			return bookList
		}
	}

	// 按分类查找
	for catId, cats := range catHash {
		if strings.Contains(cats.CategoryFullname, str) || strings.Contains(cats.CategoryShortname, str) {
			for _, book := range bookHash {
				if bookIdHash[book.Id] {
					continue
				}
				if book.Category == catId {
					bookList = append(bookList, book)
				}
				if len(bookList) == 9 {
					return bookList
				}
			}
		}
	}

	return bookList
}

func GetHotBook(sex int) []*Book {
	bookList := make([]*Book, 0)
	// 默认女频
	if sex != 1 && sex != 2 {
		sex = ChannelTypeWoman
	}
	hot := hotHash[sex]
	for _, id := range hot {
		bookList = append(bookList, bookHash[id])
		if len(bookList) == 9 {
			break
		}
	}
	return bookList
}
